from QKDNetwork import QKDNetwork
from compare_hete import Compare
import concurrent.futures

# 节点个数： 20-210          默认：60      迭代：20 + cnt * 10
# 源目对数： 10-200          默认：50      迭代：10 + cnt * 10
# 阿尔法值： 0.35-1.3        默认：0.2     迭代：0.2 + cnt * 0.05

def experiment(num_node, sd_num, alpha):
    try:
        q = QKDNetwork(showTopology=False, num_node=num_node, sd_num=sd_num, alpha=alpha, hete=True)
        c = Compare(q)
        return c.getData()
    except Exception as e:
        print("No Feasible, Pass")
        return None

def run_experiments_node_variation():
    total_tmp_var_node_num = []
    for round_idx in range(20):
        round_tmp = []
        num_node = 20 + round_idx * 10
        sd_num = 50
        alpha = 0.2
        print(f"num_node={num_node}, sd_num={sd_num}, alpha={alpha}")
        with concurrent.futures.ThreadPoolExecutor(max_workers=48) as executor:
            future_list = [
                executor.submit(experiment, num_node, sd_num, alpha) 
                for _ in range(96)
            ]
            for future in concurrent.futures.as_completed(future_list):
                data = future.result()
                if data is not None:
                    round_tmp.append(data)
                    print(data)
                else:
                    break
        total_tmp_var_node_num.append(round_tmp)
        if not round_tmp:
            break
    print(total_tmp_var_node_num)

def run_experiments_sd_variation():
    total_tmp_var_sd_num = []
    for round_idx in range(20):
        round_tmp = []
        num_node = 60
        sd_num = 10 + round_idx * 10
        alpha = 0.2
        print(f"num_node={num_node}, sd_num={sd_num}, alpha={alpha}")
        with concurrent.futures.ThreadPoolExecutor(max_workers=48) as executor:
            future_list = [
                executor.submit(experiment, num_node, sd_num, alpha) 
                for _ in range(96)
            ]
            for future in concurrent.futures.as_completed(future_list):
                data = future.result()
                if data is not None:
                    round_tmp.append(data)
                    print(data)
                else:
                    break
        total_tmp_var_sd_num.append(round_tmp)
        if not round_tmp:
            break
    print(total_tmp_var_sd_num)

def run_experiments_alpha_variation():
    total_tmp_var_alpha = []
    for round_idx in range(20):
        round_tmp = []
        num_node = 60
        sd_num = 50
        alpha = 0.2 + round_idx * 0.05
        print(f"num_node={num_node}, sd_num={sd_num}, alpha={alpha}")
        with concurrent.futures.ThreadPoolExecutor(max_workers=48) as executor:
            future_list = [
                executor.submit(experiment, num_node, sd_num, alpha) 
                for _ in range(96)
            ]
            for future in concurrent.futures.as_completed(future_list):
                data = future.result()
                if data is not None:
                    round_tmp.append(data)
                    print(data)
                else:
                    break
        total_tmp_var_alpha.append(round_tmp)
        if not round_tmp:
            break
    print(total_tmp_var_alpha)

def run_experiments_init_ps():
    total_tmp_var_node_num = []
    for round_idx in range(20):
        round_tmp = []
        num_node = 60
        sd_num = 50
        alpha = 0.2
        print(f"num_node={num_node}, sd_num={sd_num}, alpha={alpha}")
        with concurrent.futures.ThreadPoolExecutor(max_workers=48) as executor:
            future_list = [
                executor.submit(experiment, num_node, sd_num, alpha) 
                for _ in range(96)
            ]
            for future in concurrent.futures.as_completed(future_list):
                data = future.result()
                if data is not None:
                    round_tmp.append(data)
                    print(data)
                else:
                    break
        total_tmp_var_node_num.append(round_tmp)
        if not round_tmp:
            break
    print(total_tmp_var_node_num)

run_experiments_node_variation()
run_experiments_sd_variation()
run_experiments_alpha_variation()
run_experiments_init_ps()
